home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 405_01 / Discussion < prev    next >
Internet Message Format  |  1993-07-17  |  9KB

  1. From coetmeur Mon Jul 19 14:08:43 1993
  2. To: ramanand@thor.ece.uc.EDU
  3. Subject: Re: flex++/bison++
  4. Content-Type: X-sun-attachment
  5. Content-Length: 8382
  6. X-Lines: 312
  7. Status: RO
  8.  
  9. ----------
  10. X-Sun-Data-Type: text
  11. X-Sun-Data-Description: text
  12. X-Sun-Data-Name: text
  13. X-Sun-Content-Lines: 114
  14.  
  15.  
  16. > From root Thu Jul 15 20:00:27 1993
  17. > >From ramanand@thor.ece.uc.EDU Thu Jul 15 20:00:27 1993
  18. > Date: 15 Jul 93 13:57:27-0400
  19. > From: John Holmes Sr <ramanand@thor.ece.uc.EDU>
  20. > Subject: flex++/bison++
  21. > To: coetmeur@icdc.fr
  22. > MIME-version: 1.0
  23. > Content-Type> : > text/plain> ; > charset=US-ASCII> 
  24. > Content-transfer-encoding: 7bit
  25. > Hello Alain,
  26. > I recently ported the flex++/bison++ software that you have put up on the
  27. > ftp server under comp.compilers. 
  28. > First of all I would like to complement you on a job well underakten. The
  29. > documentation is quite beneficial. 
  30. > However I have been having some problems with generating multiple parsers
  31. > in the same executable. It is quite possible that my understanding of the
  32. > full capabilities of the notions of class etc. are not quite up to the
  33. > mark. I would appreciate any help you can provide.
  34. > I have tried the following approach. If there is a better way, please let
  35. > me know.
  36. >     Prepare two bison++ files. Each of them declares a different class
  37. >     for the parser. Each of them declares its LEX_BODY as = 0 (i.e. a
  38. >     pure virtual function). Prepare two flex++ files. Each of them
  39. >     inherits the properties of the corresponding parser class and defines
  40. >     the lexical analyser functions. 
  41. >     So I now have two sets of header files. 
  42. >         a. parser1.h and lex1.h
  43. >         b. parser2.h and lex2.h
  44. >     
  45. > Each set of parser/lexical analyser individually compiles correctly
  46. > with the latest gnu c++  compiler. However, if I try to include both
  47. > the lexical header files (lex1.c and lex2.c) in the main file, I get syntax
  48. > errors. The reason is in the first two lines of these header files. They
  49. > are duplicated here below:
  50. >     #ifndef FLEX_HEADER_lex__h
  51. >     #define FLEX_HEADER_lex__h
  52. >     ...
  53. >     ...
  54. > Since both these files define the same symbol FLEX_HEADER_lex__h,
  55. > obviously the second time that I include the header file, it is ignored
  56. > by the preprocessor. 
  57. > Can you give me some solutions to this. Either I could somehow rename this
  58. > symbol , or you have  a better class hierarchy that I am unaware of
  59. > currently. 
  60.  
  61.  
  62.  
  63.     The way we can use multiple parser or scanner is by changing
  64.    the name of the scanner/parser with the directive %name. it is
  65.    ESSENTIAL. By default and for compatibility the name is set to 'lex'
  66.    and 'parse', but it should be changed to a different name for each
  67.    parser/scanner. Further, the scanner and parser must not have the
  68.    same name. the name given is used as the class name, and to build
  69.    many symbol names. So you should give a %name directive, before any
  70.    other in the flex++ and bison++ files. If all the header use the
  71.    symbol FLEX_HEADER_lex__h if shoul mean that they use the same
  72.    %name. If it is not the case, it is a very important bug. I was not
  73.    able to reproduce it with the data I have.
  74.  
  75.     The way to comunicate between the scanner and the parser is not
  76.    a trivial choic, and at our site we discussed much about it. The
  77.    problems are complex since the scanner use parser constant for token
  78.    ID, the parser use the scanner function as token furnisher, and so
  79.    on...
  80.  
  81.     The way that we used is to create a derived class from the
  82.    parser class, containing the scanner itself, and redefining the
  83.    token reader function of the parser to call the scanner function of
  84.    the scanner. It seems good for many reasons:
  85.  
  86.        - the compiler (ie parser+scanner) IS essentially a PARSER,
  87.          that USE a particular SCANNER to give tokens.
  88.  
  89.        - the intermediate function that give tokens from the
  90.          scanner to the parser is a good place to put trace, and
  91.          management function (line count...)
  92.  
  93.      The design was so important to explain to new users in our
  94.     site, that I decided to build a template of compiler that is a
  95.     base to modify. It should be present in misc++, but I send it as
  96.     attachment (4 files).
  97.  
  98.     I am concient that the documentation I have given is very
  99.     technical, and assume a deep knowledge of flex, bison, C/C++, and
  100.     some design experiences.
  101.  
  102.  
  103.     Please tell me was is the result of your new try, successful or not.
  104.  
  105.     Hoping I could help you, Best regard.
  106.  
  107.  
  108.     Alain Coetmeur
  109.  
  110.  
  111. ----------
  112. X-Sun-Data-Type: rdti-source-makefile
  113. X-Sun-Data-Name: makefile
  114. X-Sun-Content-Lines: 28
  115.  
  116.  
  117.  
  118. .SUFFIXES : .cc .y .l $(SUFFIXES)
  119.  
  120. .cc.o :
  121.     CC   -I$(CENTERCCLIBDIR)/incl -c  $*.cc
  122.  
  123. .y.cc :
  124.     bison++ -d  -o $*.cc -h $*.h  $*.y
  125. .l.cc :
  126.     flex++    -h$*.h -o$*.cc $*.l
  127. .y.h :
  128.     bison++ -d  -o $*.cc -h $*.h  $*.y
  129. .l.h :
  130.     flex++    -h$*.h -o$*.cc $*.l
  131.  
  132. all : compiler
  133.  
  134. MyCompiler.o : MyCompiler.cc MyParser.h MyScanner.h
  135.  
  136. MyParser.o : MyParser.cc MyParser.h
  137.  
  138. MyScanner.o : MyScanner.cc MyScanner.h MyParser.h
  139.  
  140.  
  141. compiler : MyCompiler.o MyParser.o MyScanner.o
  142.     CC  -o $@ MyCompiler.o MyParser.o MyScanner.o
  143.  
  144. ----------
  145. X-Sun-Data-Type: rdtq-source-l
  146. X-Sun-Data-Name: MyScanner.l
  147. X-Sun-Content-Lines: 42
  148.  
  149. /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
  150. /*
  151.  * Nom du Fichier :     |>nom_fichier<|
  152.  * Titre :         |>Titre<|
  153.  * Auteur:        |>auteur<|        
  154.  * Date de creation :    |>dateCreation<|
  155.  */
  156. /* Description :
  157.  *    Document de reference : |>doc<|
  158.  *    Objet : |>objet<|
  159.  *
  160.  */
  161. /* 
  162.  * historique :
  163.  * |>date<|    |>auteur<|    |>objet<|
  164.  */
  165. /* -------------- declaration section -------------- */
  166. %name MyScanner
  167.  
  168. %define LEX_PARAM YY_MyParser_STYPE *val,YY_MyParser_LTYPE *loc
  169. %define MEMBERS public: int theLine,theColumn;
  170. %define CONSTRUCTOR_INIT : theLine(1),theColumn(1)
  171. %header{ 
  172. #include "MyParser.h"
  173. %}
  174.  
  175. %{
  176. static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
  177. %}
  178.  
  179. /* -------------- rules section -------------- */
  180. SPACES [ \t]+
  181. %%
  182. "\n"    {val->ctype='\n';
  183.          theLine++;theColumn=1;
  184.          return MyParser::EOL_TOKEN; }
  185. .    {
  186.          val->ctype=yytext[0];
  187.          theColumn++;
  188.          return MyParser::CHAR_TOKEN; }
  189. <<EOF>> { yyterminate();}
  190. %%
  191. ----------
  192. X-Sun-Data-Type: rdtq-source-y
  193. X-Sun-Data-Name: MyParser.y
  194. X-Sun-Content-Lines: 50
  195.  
  196. /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
  197. /*
  198.  * Nom du Fichier :     |>nom_fichier<|
  199.  * Titre :         |>Titre<|
  200.  * Auteur:        |>auteur<|
  201.  * Date de creation :    |>dateCreation<|
  202.  */
  203. /* Description :
  204.  *    Document de reference : |>doc<|
  205.  *    Objet : |>objet<|
  206.  *
  207.  */
  208. /*
  209.  * historique :
  210.  * |>date<|    |>auteur<|    |>objet<|
  211.  */
  212. /* -------------- declaration section -------------- */
  213.  
  214. %name MyParser
  215. %define LSP_NEEDED
  216. %define ERROR_BODY =0
  217. %define LEX_BODY =0
  218. %header{
  219. #include <stdio.h>
  220. %}
  221.  
  222. %union {
  223.     int itype;    /* for count */
  224.     char ctype;    /* for char */
  225.     }
  226. %token <ctype> EOL_TOKEN CHAR_TOKEN
  227. %type <itype> file line lines chars
  228. %start file
  229.  
  230. /* -------------- rules section -------------- */
  231. /* Sample parser. Does count Chars in a line, and lines in file */
  232. %%
  233. file    : lines
  234.     {printf("nlines=%d\n",$1); /* show line count */}
  235.     ;
  236. lines     : line {$$=1; /* first line of all */}
  237.     | lines line {$$=$1+1;    /* count one more line */}
  238.     ;
  239. line     : chars EOL_TOKEN {$$=$1;printf("nchars=%d\n",$1); /* show char count */}
  240.     ;
  241. chars    : CHAR_TOKEN { $$=1;/* first char of line */}
  242.     | chars CHAR_TOKEN {$$=$1+1; /* count one more char */}
  243.     ;
  244. %%
  245. /* -------------- body section -------------- */
  246. ----------
  247. X-Sun-Data-Type: rdtq-source-cc
  248. X-Sun-Data-Name: MyCompiler.cc
  249. X-Sun-Content-Lines: 52
  250.  
  251. static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
  252. //
  253. // Nom du Fichier :     |>nom_fichier<|
  254. // Titre :         |>Titre<|
  255. // Auteur:        |>auteur<|        
  256. // Date de creation :    |>dateCreation<|
  257. //
  258. // Description :
  259. //    Document de reference : |>doc<|
  260. //    Objet : |>objet<|
  261. //
  262. //
  263. // 
  264. // historique :
  265. // |>date<|    |>auteur<|    |>objet<|
  266. //
  267. #include "MyScanner.h"
  268. #include "MyParser.h"
  269.  
  270. class MyCompiler : public MyParser
  271. {private:
  272.  MyScanner theScanner;
  273.  public:
  274.  virtual int yylex();
  275.  virtual void yyerror(char *m);
  276.  MyCompiler() 
  277.   {};
  278. };
  279.  
  280. int MyCompiler::yylex()
  281. {
  282.  yylloc.first_line=theScanner.theLine;
  283.  yylloc.first_column=theScanner.theColumn;
  284.  int token=theScanner.yylex(&yylval,&yylloc);
  285.  yylloc.last_line=theScanner.theLine;
  286.  yylloc.la